package gupao.concurrency.utils;

import org.hyperic.sigar.Cpu;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.Set;

public class SigarUtil {

   /* static class CpuTime{
        Thread t;

    }*/

    final static ThreadMXBean tmbean = ManagementFactory.getThreadMXBean();
    static {
        tmbean.setThreadCpuTimeEnabled(true);
        tmbean.setThreadContentionMonitoringEnabled(true);
    }

    final static Sigar sigar = new Sigar();

    /*static volatile boolean flag = true;

    static final BlockingQueue<Thread> threadQueue = new LinkedBlockingQueue<>(100);*/

    static int cpuNum = Runtime.getRuntime().availableProcessors();

    /*final static Future<?> f = ThreadPoolService.getOrCreateThreadPoolExecutor("sigar",1,1)
            .submit(() -> {
                while(flag){
                    try{
                        Thread t = threadQueue.poll(10, TimeUnit.MILLISECONDS);

                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });*/

    public static String calcThreadCpuRatio(long lastThreadTime, long lastCpuTime){
        long curThreadCpuTime = calcThreadTime(Thread.currentThread().getId());
        long curCpuTime = calcCpuTime();
        double ratio = (curThreadCpuTime - lastThreadTime) * cpuNum * 1.0D / (curCpuTime - lastCpuTime) / 1000000;
        return Thread.currentThread().getName() + " cpu ratio:" + ratio;
    }

    public static long calcThreadTime(long threadId){
        return tmbean.getThreadCpuTime(threadId);
    }

    public static long calcThreadsTime(Set<Long> threadIds){
        long time = 0;
        for( long tid : threadIds ){
            time += calcThreadTime(tid);
        }
        return time;
    }

    public static long calcCpuTime(){
        try {
            Cpu[] cpus = sigar.getCpuList();
            long cpuTime = 0;
            for (Cpu cpu : cpus) {
                cpuTime += cpu.getTotal();
            }
            return cpuTime;
        } catch (SigarException e) {
            throw new RuntimeException();
        }
    }
}
